package com.ruiao.tools.menjin;

import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Process;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;

import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import com.ruiao.tools.R;
import com.ruiao.tools.url.URLConstants;
import com.ruiao.tools.utils.AsynHttpTools;
import com.ruiao.tools.utils.HttpUtil;
import com.ruiao.tools.utils.SPUtils;
import com.ruiao.tools.utils.ToastHelper;

import org.jetbrains.annotations.NotNull;
import org.json.JSONObject;

import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Callable;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import cn.wandersnail.bluetooth.BTManager;
import cn.wandersnail.bluetooth.ConnectCallback;
import cn.wandersnail.bluetooth.Connection;
import cn.wandersnail.bluetooth.DiscoveryListener;
import cn.wandersnail.bluetooth.EventObserver;
import cn.wandersnail.bluetooth.WriteCallback;
import cn.wandersnail.commons.helper.PermissionsRequester;
import cn.wandersnail.commons.util.ToastUtils;
import cn.wandersnail.widget.listview.BaseListAdapter;
import cn.wandersnail.widget.listview.BaseViewHolder;
import cn.wandersnail.widget.listview.PullRefreshLayout;
import cz.msebera.android.httpclient.Header;

/**
 * date: 2019/8/4 15:13
 * author: zengfansheng
 */
public class ScanActivity extends AppCompatActivity implements EventObserver {
    String mn;
    Context context;
    private Connection connection;
    private ListAdapter listAdapter;
    private PullRefreshLayout refreshLayout;
    private TextView tvEmpty;
    private List<Device> devList = new ArrayList<>();
    private PermissionsRequester permissionsRequester;

    private static class Device {
        BluetoothDevice device;
        int rssi;

        Device(BluetoothDevice device, int rssi) {
            this.device = device;
            this.rssi = rssi;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (!(o instanceof Device)) {
                return false;
            }
            Device device1 = (Device) o;
            return device.equals(device1.device);
        }

        @Override
        public int hashCode() {
            return Objects.hash(device);
        }
    }
    
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);
        context = this;
        initViews();
        mn = getIntent().getStringExtra("MN");
        BTManager.isDebugMode = true;
        BTManager.getInstance().addDiscoveryListener(discoveryListener);
        initialize();
    }

    private void initViews() {
        refreshLayout = findViewById(R.id.refreshLayout);
        ListView lv = findViewById(R.id.lv);
        tvEmpty = findViewById(R.id.tvEmpty);
        refreshLayout.setColorSchemeColors(ContextCompat.getColor(this, R.color.colorAccent));
        listAdapter = new ListAdapter(this, devList);
        lv.setAdapter(listAdapter);
        lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
                final AlertDialog.Builder normalDialog =
                        new AlertDialog.Builder(ScanActivity.this);
                normalDialog.setIcon(R.mipmap.ic_lonch);
                normalDialog.setTitle("开启门禁");
                normalDialog.setMessage("确认开启此门禁？");
                normalDialog.setPositiveButton("确定",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                connect(position);
                            }
                        });
                normalDialog.setNegativeButton("关闭",
                        new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {

                            }
                        });
                // 显示
                normalDialog.show();

            }
        });
//        lv.setOnItemClickListener((parent, view, position, id) -> {

//            BluetoothDevice devicex =  devList.get(position).device;
//            connection = BTManager.getInstance().createConnection(devicex, ScanActivity.this);
//            if (connection == null) {
//                finish();
//                return;
//            }
//            connection.connect(null, new ConnectCallback() {
//                @Override
//                public void onSuccess() {
//                    if (connection.isConnected()) {
//
//                    }
//                }
//
//                @Override
//                public void onFail(@NonNull String errMsg, @Nullable Throwable e) {
//                    runOnUiThread(() -> ToastHelper.shortToast(context,"连接失败！"));
//                }
//            });
//        }
//        );
        refreshLayout.setOnRefreshListener(() -> {
            if (BTManager.getInstance().isInitialized()) {
                BTManager.getInstance().stopDiscovery();
                doStartDiscovery();
            }
            refreshLayout.postDelayed(() -> refreshLayout.setRefreshing(false), 500);
        });
    }

    private void connect(int position) {
        BluetoothDevice devicex =  devList.get(position).device;
        connection = BTManager.getInstance().createConnection(devicex, ScanActivity.this);
        if (connection == null) {
            finish();
            return;
        }
        connection.connect(null, new ConnectCallback() {
            @Override
            public void onSuccess() {
                if (connection.isConnected()) {

                }
            }

            @Override
            public void onFail(@NonNull String errMsg, @Nullable Throwable e) {
                runOnUiThread(() -> ToastHelper.shortToast(context,"连接失败！"));
            }
        });
    }


    @Override
    public void onConnectionStateChanged(@NonNull BluetoothDevice device, int state) {
        String name = device.getName();

        if(state == 4){
            ToastHelper.shortToast(context,name+"连接成功");
            connection.write(null, HexUtils.INSTANCE.hexStringToBytes("71"), new WriteCallback() {
                @Override
                public void onWrite(@NonNull BluetoothDevice device, @NonNull String tag, @NonNull byte[] value, boolean result) {
                    ToastHelper.shortToast(context,HexUtils.INSTANCE.bytesToHexString(value));
                }
            });
            RequestParams pa = new RequestParams();
            pa.put("username", SPUtils.get(context,"usernam",""));
            if(TextUtils.isEmpty(mn)){
                return;
            }
            pa.put("MN",mn);
            AsynHttpTools.httpGetMethodByParams(URLConstants.BLE_MENJING,pa, new JsonHttpResponseHandler(){
                @Override
                public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
                    super.onSuccess(statusCode, headers, response);

                }
            });

        }


    }




    @Override
    protected void onDestroy() {
        super.onDestroy();
        BTManager.getInstance().release();
        Process.killProcess(Process.myPid());
    }

    private DiscoveryListener discoveryListener = new DiscoveryListener() {
        @Override
        public void onDiscoveryStart() {
            invalidateOptionsMenu();
        }

        @Override
        public void onDiscoveryStop() {
            invalidateOptionsMenu();
        }

        @Override
        public void onDiscoveryError(int errorCode, @NonNull String errorMsg) {
            switch(errorCode) {
                case DiscoveryListener.ERROR_LACK_LOCATION_PERMISSION://缺少定位权限
                    break;
                case DiscoveryListener.ERROR_LOCATION_SERVICE_CLOSED://位置服务未开启
                    break;
                case DiscoveryListener.ERROR_SCAN_FAILED://搜索失败
                    ToastUtils.showShort("搜索出错：" + errorCode);
                    break;
            }
        }

        @Override
        public void onDeviceFound(@NonNull BluetoothDevice device, int rssi) {
            tvEmpty.setVisibility(View.INVISIBLE);
            Device dev = new Device(device, rssi);
            if (!devList.contains(dev)) {
                devList.add(dev);
                listAdapter.notifyDataSetChanged();
            }
        }
    };
    
    //需要进行检测的权限
    private List<String> getNeedPermissions() {
        List<String> list = new ArrayList<>();
        list.add(Manifest.permission.ACCESS_FINE_LOCATION);//target sdk版本在29以上的需要精确定位权限才能搜索到蓝牙设备
        return list;
    }

    @Override
    protected void onResume() {
        super.onResume();
        Log.d("Main", "onResume");
        if (BTManager.getInstance().isInitialized()) {
            if (BTManager.getInstance().isBluetoothOn()) {
                doStartDiscovery();
            } else {
                startActivity(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE));
            }
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        if (BTManager.getInstance().isInitialized()) {
            BTManager.getInstance().stopDiscovery();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.scan, menu);
        MenuItem item = menu.findItem(R.id.menuProgress);
        item.setActionView(R.layout.toolbar_indeterminate_progress);
        item.setVisible(BTManager.getInstance().isDiscovering());
        return super.onCreateOptionsMenu(menu);
    }

    private void initialize() {
        //动态申请权限
        permissionsRequester = new PermissionsRequester(this);
        permissionsRequester.setCallback(list -> {
            
        });
        permissionsRequester.checkAndRequest(getNeedPermissions());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        permissionsRequester.onRequestPermissionsResult(requestCode, permissions, grantResults);
    }

    private void doStartDiscovery() {
        devList.clear();
        listAdapter.notifyDataSetChanged();
        tvEmpty.setVisibility(View.VISIBLE);
        BTManager.getInstance().startDiscovery();
    }

    private static class ListAdapter extends BaseListAdapter<Device> {

        ListAdapter(@NotNull Context context, @NotNull List<Device> list) {
            super(context, list);
        }

        @NotNull
        @Override
        protected BaseViewHolder<Device> createViewHolder(int i) {
            return new BaseViewHolder<Device>() {
                TextView tvName;
                TextView tvAddr;
                TextView tvRssi;

                @Override
                public void onBind(@NonNull Device device, int i) {
                    tvName.setText(TextUtils.isEmpty(device.device.getName()) ? "N/A" : device.device.getName());
                    tvAddr.setText(device.device.getAddress());
                    tvRssi.setText("" + device.rssi);
                }

                @NotNull
                @Override
                public View createView() {
                    View view = View.inflate(context, R.layout.item_scan, null);
                    tvName = view.findViewById(R.id.tvName);
                    tvAddr = view.findViewById(R.id.tvAddr);
                    tvRssi = view.findViewById(R.id.tvRssi);
                    return view;
                }
            };
        }
    }
}
